package com.bitcointoolkit.web.aspect;

import com.alibaba.fastjson.JSON;
import com.bitcointoolkit.web.support.Result;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * [类描述]
 *
 * @author caican
 * @date 2018/6/26
 */

@Order(1)
@Aspect
@Component
public class ServiceAspect {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Around("execution(* com.bitcointoolkit.web.service..*Impl.*(..))\")")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String clazzName = joinPoint.getTarget().getClass().getName();
        String mName = joinPoint.getSignature().getName();
        Class returnType = ((MethodSignature) joinPoint.getSignature()).getReturnType();
        Object[] args = joinPoint.getArgs();
        try {
            //请求日志
            printRequestLog(clazzName, mName, args);
            //执行方法
            long start = System.currentTimeMillis();
            Object returnObj = joinPoint.proceed();

            printResultLog(clazzName, mName, returnObj, System.currentTimeMillis() - start);
            return returnObj;
        } catch (Exception e) {
            logger.error("系统异常", e);
            return getResultObj(returnType, false, "", "系统异常");
        }
    }

    public void printRequestLog(String clazz, String mName, Object[] args) {
        if (args != null) {
            if (logger.isInfoEnabled()) {
                String request = JSON.toJSONString(args);
                logger.info(clazz + "  " + mName + " request is " + request);
            }
        } else {
            logger.info(clazz + "  " + mName + " no request.");
        }
    }

    //有参并有返回值的方法
    public void printResultLog(String clazz, String mName, Object returnObj, long ms) {

        if (logger.isInfoEnabled()) {
            String result = JSON.toJSONString(returnObj);
            logger.info(clazz + "  " + mName + " result is " + result + " ms is " + ms);
        }
    }

    private <T> T getResultObj(Class<T> cls, boolean success, String code, String desc) {
        try {
            T ret = cls.newInstance();
            if (!(ret instanceof Result)) {
                throw new RuntimeException("返回类型必须继承BaseResult");
            }
            ((Result) ret).setSuccess(success);
            ((Result) ret).setCode(code);
            ((Result) ret).setMsg(desc);
            return ret;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
